// DlgSendRequest.cpp : implementation file
//

#include "stdafx.h"
#include "Celsus.h"
#include "DlgSendRequest.h"
#include "DlgPreviewHTML.h"
#include "SendMessage.h"
#include "FTPTransferDlg.h"
#include "DlgConfirm.h"
#include "DlgPromptMaterial.h"

#include <cderr.h>


// CDlgSendRequest dialog

#define OFN_BUFFER_SIZE 10240
#define NOTES_PICK_LIST 10

IMPLEMENT_DYNAMIC(CDlgSendRequest, CDialog)

CDlgSendRequest::CDlgSendRequest(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgSendRequest::IDD, pParent)
	, m_szDescription(_T(""))
	, m_szTo(_T(""))
	, m_bDeferEmail(FALSE)
	, m_bOverrideEmailCheck(FALSE)
	, m_bDeleteFile(FALSE)
	, m_szStatus(_T(""))
	, m_bPreviewEmail(FALSE)
	, m_dServiceFee(0)
	, m_dCopyrightFee(0)
	, m_dUserFeeMax(0)
	, m_dMiscFee(0)
	, m_nMaterial(0)
	, m_nSendType(0)
{
	m_nItemID = 0;
	m_nUserID = 0;
	m_nUserCode = 0;
	m_nStaffID = 0;
	m_nLibraryID = 0;
	m_nCollectionID = 0;
	m_nStatus = -1;
	m_bEnableThumbnail = FALSE;
	m_bSendMultiple = FALSE;
	m_bShowThumbnail = FALSE;
	m_bManual = FALSE;
	m_nFileIndex = 0;

	m_nWindowWidthShow = 0;
	m_nWindowWidthNoShow = 0;

	m_pszaCollection = NULL;
}

CDlgSendRequest::~CDlgSendRequest()
{
}

void CDlgSendRequest::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO_FILE_NAME, m_ctrlFiles);
	DDX_Text(pDX, IDC_EDIT_DESCRIPTION, m_szDescription);
	DDX_Text(pDX, IDC_EDIT_INFORMATION, m_szInformation);
	DDX_Text(pDX, IDC_EDIT_EMAIL, m_szTo);
	DDX_Check(pDX, IDC_CHECK_DEFER_SEND, m_bDeferEmail);
	DDX_Check(pDX, IDC_CHECK_OVERRIDE_EMAIL, m_bOverrideEmailCheck);
	DDX_Check(pDX, IDC_CHECK_DELETE_AFTER_SEND, m_bDeleteFile);
	DDX_Text(pDX, IDC_STATIC_STATUS, m_szStatus);
	DDX_Check(pDX, IDC_CHECK_PREVIEW_EMAIL, m_bPreviewEmail);
	DDX_Text(pDX, IDC_EDIT_SERVICE_FEE, m_dServiceFee);
	DDV_MinMaxDouble(pDX, m_dServiceFee, 0.00, 99999.99);
	DDX_Text(pDX, IDC_EDIT_COPYRIGHT_FEE, m_dCopyrightFee);
	DDV_MinMaxDouble(pDX, m_dCopyrightFee, 0.00, 99999.99);
	DDX_Control(pDX, IDC_COMBO_COLLECTION, m_ctrlCollection);
	DDX_Text(pDX, IDC_EDIT_MISC_FEE, m_dMiscFee);
	DDX_Radio(pDX, IDC_RADIO_SEND_TYPE_1, m_nSendType);
	DDX_Radio(pDX, IDC_RADIO_MATERIAL_1, m_nMaterial);
	DDX_Control(pDX, IDC_EDIT_EMAIL, m_ctrlEmail);
	DDX_Control(pDX, IDC_EDIT_DESCRIPTION, m_ctrlDescription);
	DDX_Control(pDX, IDC_EDIT_INFORMATION, m_ctrlInformation);
	DDX_Control(pDX, IDC_EXPLORER_REQUESTER, m_wbRequester);
	DDX_Control(pDX, IDC_EXPLORER_PREVIEW, m_wbPreview);
}

BEGIN_MESSAGE_MAP(CDlgSendRequest, CDialog)
	ON_BN_CLICKED(IDC_BUTTON_THUMBNAIL, &CDlgSendRequest::OnBnClickedButtonThumbnail)
	ON_BN_CLICKED(IDCANCEL, &CDlgSendRequest::OnBnClickedCancel)
	ON_CBN_SELCHANGE(IDC_COMBO_COLLECTION, &CDlgSendRequest::OnCbnSelchangeComboCollection)
	ON_BN_CLICKED(IDC_BUTTON_OPEN, &CDlgSendRequest::OnBnClickedButtonOpen)
	ON_BN_CLICKED(IDC_BUTTON_BROWSE_FILE, &CDlgSendRequest::OnBnClickedButtonBrowseFile)
	ON_BN_CLICKED(IDC_BUTTON_DELETE, &CDlgSendRequest::OnBnClickedButtonDelete)
END_MESSAGE_MAP()


// CDlgSendRequest message handlers

BOOL CDlgSendRequest::OnInitDialog()
{
	CDialog::OnInitDialog();
	USES_CONVERSION;

	ASSERT( m_pszaStatus != NULL );
	ASSERT( m_pszaPriority != NULL );
	ASSERT( m_pszaMethod != NULL );
	ASSERT( m_pszaLibrary != NULL );
	ASSERT( m_pszaCollection != NULL );
	ASSERT( m_pszaReferrals != NULL );	
	ASSERT( m_pszaILL != NULL );

	// init sets
	appConfig.m_SQL.InitRequestSet( &m_Request );
	appConfig.m_SQL.InitUserSet( &m_User );

	// check for valid ID
	if( m_nItemID < 0 )
	{
		EndDialog( IDCANCEL );
		return TRUE;
	}

	// get files
	if( !GetFiles() )
	{
		// error with message file end dialog
		EndDialog( IDCANCEL );
		return FALSE;
	}
	// set combobox item
	m_ctrlFiles.SetCurSel( m_nFileIndex );

	// preferences
	m_bShowThumbnail = AfxGetApp()->GetProfileInt( _T("Settings"), _T("ShowThumbnail"), 0 );

	////build file list disable thumbnail if not PDF
	//for( INT nCount = 0; nCount < m_ctrlFiles.GetCount(); nCount++ )
	//{
	//	CString szFile;
	//	// get from file
	//	m_ctrlFiles.GetLBText( nCount, szFile );
	//	// split path
	//	TCHAR drive[_MAX_DRIVE];
	//	TCHAR dir[_MAX_DIR];
	//	TCHAR fname[_MAX_FNAME];
	//	TCHAR ext[_MAX_EXT];
	//	_tsplitpath_s( szFile, drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, ext, _MAX_EXT );
	//}

	// thumnail enabled
	if( m_bEnableThumbnail )
	{
		// get file from
		CString szFileFrom;
		GetDlgItemText( IDC_COMBO_FILE_NAME, szFileFrom );
		// navigate to file
		m_wbPreview.Navigate( szFileFrom, NULL, NULL, NULL, NULL );

	}
	else
	{
		// disable thumbnail button
		GetDlgItem( IDC_BUTTON_THUMBNAIL )->EnableWindow( FALSE );
		// no thumbnail available
		m_bShowThumbnail = FALSE;
	}

	// get window positions
	CRect rect;
	CRect rectPreview;
	GetWindowRect( rect );
	m_wbPreview.GetWindowRect( rectPreview );
	// save original
	m_nWindowWidthShow = rect.Width();
	m_nWindowWidthNoShow = rect.Width() - ( rectPreview.Width() + 22 );

	ASSERT( m_pszaCollection != NULL );

	if( !m_bManual )
	{
		// get request
		appConfig.m_SQL.GetRequestSet( &m_Request, m_nItemID );
		// get variables
		m_nCollectionID = m_Request.m_collection_id;
		// set if sticky
		if( appConfig.m_General.bUseSitckyCollection )
			m_nCollectionID = AfxGetApp()->GetProfileInt( _T("Settings"), _T("StickyCollection"), m_nCollectionID );
	}

	// check for valid staff
	if( m_nStaffID > 0 )
	{
		// get staff
		STAFF_SET Staff;
		appConfig.m_SQL.GetStaffSet( &Staff, m_nStaffID );
		// override with default
		if( Staff.m_default_collection >= 0 )		
			m_nCollectionID = Staff.m_default_collection;
	}

	INT nCurSel = 0;
	INT nSel = 0;
	CString szTemp;

	// set m_ctrlCollection
	m_ctrlCollection.Init();
	m_ctrlCollection.SetMode();
	for( INT nIndex = 0; nIndex < m_pszaCollection->GetCount(); nIndex++ )
	{
		szTemp = m_pszaCollection->GetAt( nIndex );
		if( !szTemp.IsEmpty() )
		{
			nSel = m_ctrlCollection.AddString( szTemp );
			m_ctrlCollection.SetItemData( nSel, nIndex );
			if( m_nCollectionID == nIndex )
				nCurSel = nSel;
		}
	}
	m_ctrlCollection.SetCurSel( nCurSel );

	// set window position
	if( m_bShowThumbnail )
		SetWindowPos( NULL, 0, 0, m_nWindowWidthShow, rect.Height(), SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
	else
		SetWindowPos( NULL, 0, 0, m_nWindowWidthNoShow, rect.Height(), SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );

	// init quick picks
	m_ctrlDescription.Init();
	m_ctrlDescription.SetMode();
	m_ctrlInformation.Init();
	m_ctrlInformation.SetMode();
	m_ctrlEmail.Init();
	m_ctrlEmail.SetMode();

	// if not manual get info
	if( !m_bManual )
	{
		// set title
		CString szText;
		szText.Format( _T("Sending file for: %.8ld"), m_nItemID );
		SetWindowText( szText );

		// set variables
		m_szRequest = m_Request.m_request;
		m_szDateIn = m_Request.m_date_in.Format( appConfig.m_General.szDateFormat );
		m_dServiceFee = m_Request.m_fee_service;
		m_dCopyrightFee = m_Request.m_fee_copyright;
		m_dMiscFee = m_Request.m_fee_misc;
		m_nCopyright = m_Request.m_copyright;
		m_nUserID = m_Request.m_user_id;
		m_szDescription = m_Request.m_notes;

		// get user
		appConfig.m_SQL.GetUserSet( &m_User, m_nUserID );
		// get variables
		if( !m_User.m_altemail1.IsEmpty() && appConfig.m_Email.bSendToAlternateEmail )
			m_szTo = m_User.m_altemail1;
		else
			m_szTo = m_User.m_email;
		m_nUserCode = m_User.m_activation_code;
		m_dUserFeeMax = m_User.m_fee_max;

		// set info size
		GetDlgItem( IDC_EXPLORER_REQUESTER )->SetWindowPos( NULL, 10, 10, 360, 65, SWP_NOZORDER );
		GetDlgItem( IDC_STATIC_INFORMATION )->ShowWindow( SW_HIDE );
		GetDlgItem( IDC_EDIT_INFORMATION )->ShowWindow( SW_HIDE );

		// init info
		m_wbRequester.Navigate( _T("About:Blank"), NULL, NULL, NULL, NULL );

		if( !appConfig.m_General.szSendInfoFile.IsEmpty() )
		{
			CString szHTMLRequester;
			// clear requester
			appConfig.ClearHTML( &m_wbRequester );
			// read requester info file
			szHTMLRequester = appConfig.ReadFile( appConfig.m_General.szSendInfoFile );
			// format macros
			FormatMacros( &szHTMLRequester );
			// set HTML
			appConfig.SetHTML( &m_wbRequester, szHTMLRequester );
		}

		// disable email
		GetDlgItem( IDC_EDIT_EMAIL )->EnableWindow( FALSE );
		// set notes
		GetDlgItem( IDC_STATIC_DESCRIPTION )->SetWindowText( _T("User Notes") );

		// get pick list
		CString szNotes;
		CString resToken;

		INT curPos = 0;
		szNotes = AfxGetApp()->GetProfileString( _T("Settings"), _T("PickList_Notes") );
		resToken = szNotes.Tokenize(_T("\n\r"),curPos);
		while( resToken != _T("") )
		{
			m_szaDescription.Add( resToken );
			m_ctrlDescription.AddSearchString( resToken );		
			resToken = szNotes.Tokenize( _T("\n\r"), curPos );
		};
	}
	else
	{
		// get pick list
		CArray<EXTERNAL_ILL_SET> aIll;
		appConfig.m_SQL.GetExternIllSet( &aIll );
		// fill list
		for( INT nIndex = 0; nIndex < aIll.GetCount(); nIndex++ )
			m_ctrlEmail.AddSearchString( aIll.GetAt( nIndex ).m_email );

		// init info
		m_wbRequester.Navigate( _T("About:Blank"), NULL, NULL, NULL, NULL );
		// set HTML (could make it file for more information)
		appConfig.SetHTML( &m_wbRequester, _T("Please enter email address and file description.") );

		// hide info, move it off screen as hiding causes error
		GetDlgItem( IDC_EXPLORER_REQUESTER )->MoveWindow( 0, 0, 0, 0 );

		// set info size
		GetDlgItem( IDC_STATIC_INFORMATION )->MoveWindow( 10, 130, 360, 14 );
		GetDlgItem( IDC_EDIT_INFORMATION )->MoveWindow( 10, 145, 340, 24 );

		// move edit boxes
		GetDlgItem( IDC_STATIC_FILE_NAME )->MoveWindow( 10, 10, 360, 14 );
		GetDlgItem( IDC_COMBO_FILE_NAME )->MoveWindow( 10, 25, 340, 24 );
		GetDlgItem( IDC_BUTTON_BROWSE_FILE )->MoveWindow( 350, 25, 25, 20 );		

		GetDlgItem( IDC_STATIC_EMAIL )->MoveWindow( 10, 50, 360, 14 );
		GetDlgItem( IDC_EDIT_EMAIL )->MoveWindow( 10, 65, 340, 24 );

		GetDlgItem( IDC_STATIC_DESCRIPTION )->MoveWindow( 10, 90, 360, 14 );
		GetDlgItem( IDC_EDIT_DESCRIPTION )->MoveWindow( 10, 105, 340, 24 );

		// get pick list
		CString szNotes;
		CString resToken;

		INT curPos = 0;
		szNotes = AfxGetApp()->GetProfileString( _T("Settings"), _T("PickList_Notes") );
		resToken = szNotes.Tokenize(_T("\n\r"),curPos);
		while( resToken != _T("") )
		{
			m_szaInformation.Add( resToken );
			m_ctrlInformation.AddSearchString( resToken );		
			resToken = szNotes.Tokenize( _T("\n\r"), curPos );
		};

		// set title
		SetWindowText( _T("Manually Sending File") );
		// set check boxes
		m_nSendType = SEND_FTP;
		// preview before email
		m_bPreviewEmail = TRUE;
		// set focus
		GetDlgItem( IDC_EDIT_EMAIL )->SetFocus();
	}

	// get library info
	LIBRARY_LOOKUP Library;
	appConfig.m_SQL.GetDescriptionLibrary( &Library, m_nLibraryID );
	m_szFrom = Library.szEmail;
	m_szName = Library.szName;
	m_szSubject = Library.szSubject;

	// set material
	if( !m_bManual )
	{
		// check for electronic
		COLLECTION_LOOKUP Collection;
		appConfig.m_SQL.GetDescriptionCollection( &Collection, m_Request.m_collection_id );
		m_nMaterial = Collection.nElectronic;
		// set electronc
		if( appConfig.m_General.bUseSitckyCollection )
			m_nMaterial = AfxGetApp()->GetProfileInt( _T("Settings"), _T("StickyMaterial"), m_nMaterial );
			
		// disable web server
		GetDlgItem( IDC_RADIO_SEND_TYPE_3 )->EnableWindow( FALSE );
	}
	else
	{
		// disable web server
		GetDlgItem( IDC_RADIO_SEND_TYPE_1 )->EnableWindow( FALSE );
	}

	// set defaults
	m_bDeleteFile = appConfig.m_General.bRemoveFileAfterSend;

	// show finalcials
	if( appConfig.m_Options.bDisableFinacial )
	{
		GetDlgItem( IDC_STATIC_SERVICE_FEE )->ShowWindow( SW_HIDE );
		GetDlgItem( IDC_EDIT_SERVICE_FEE )->ShowWindow( SW_HIDE );

		GetDlgItem( IDC_STATIC_MISC_FEE )->ShowWindow( SW_HIDE );
		GetDlgItem( IDC_EDIT_MISC_FEE )->ShowWindow( SW_HIDE );

		GetDlgItem( IDC_STATIC_COPYRIGHT_FEE )->ShowWindow( SW_HIDE );
		GetDlgItem( IDC_EDIT_COPYRIGHT_FEE )->ShowWindow( SW_HIDE );
	}

	// hide FTP
	if( !appConfig.m_FTP_ILL.szServerName.IsEmpty() || !appConfig.m_FTP_ILL.szServerName.IsEmpty() )
		GetDlgItem( IDC_RADIO_SEND_TYPE_3 )->ShowWindow( SW_SHOW );
	else
		GetDlgItem( IDC_RADIO_SEND_TYPE_3 )->ShowWindow( SW_HIDE );

	// get from file
	CString szFileFrom;
	m_ctrlFiles.GetLBText( 0, szFileFrom );

	// get file size
	TCHAR size[_MAX_FNAME];
	CFileStatus filestatus;
	CFile::GetStatus( szFileFrom, filestatus );
	StrFormatByteSize( (LONGLONG)filestatus.m_size, size, sizeof(size) );

	// set staus
	m_szStatus.Format( _T("Ready to send file.\t(size = %s)"), size );

	// update data
	UpdateData( FALSE );

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void CDlgSendRequest::OnOK()
{
	//CString szFile;
	CString szFileTo;
	CString szFileFrom;
	CSendMessage SendMsg;

	// update data
	UpdateData();

	// check description on manual
	if( m_bManual )
	{
		// check description
		if( m_szDescription.IsEmpty() )
		{
			AfxMessageBox( IDS_NO_DESCRIPTION, MB_OK | MB_ICONSTOP );
			return;
		}
	}

	// set status
	SetDlgItemText( IDC_STATIC_STATUS, _T("Checking Email Address...") );
	// trim white space
	m_szTo.Trim();
	// check email
	if( m_szTo.IsEmpty() )
	{
		AfxMessageBox( IDS_NOEMAIL_ERROR, MB_OK | MB_ICONSTOP );
		return;
	}
	// validate email
	if( !SendMsg.ValidateEmail( m_szTo ))
		return;

	// prompt for material
	BOOL bPromptMaterial = (BOOL)AfxGetApp()->GetProfileInt( _T("Settings"), _T("PromptMaterial"), 1 );
	if( bPromptMaterial )
	{
		// get material from dialog
		CDlgPromptMaterial dlgMaterial;
		dlgMaterial.m_nMaterial = m_nMaterial;
		if( dlgMaterial.DoModal() == IDCANCEL )
			return;
		m_nMaterial = dlgMaterial.m_nMaterial;
		// update data
		UpdateData(FALSE);
	}

	// get user type info
	USER_TYPE_LOOKUP UserType;
	appConfig.m_SQL.GetDescriptionUserType( &UserType, m_User.m_type );

	// check ILL email
	if( m_bManual )
	{
		EXTERNAL_ILL_SET Ill;
		// get ILL
		appConfig.m_SQL.GetExternIllSet( &Ill, m_szTo );
		// check for previous
		if( Ill.m_id < 0 )
		{
			if( AfxMessageBox( _T("Email address not found in External ILL list.\n\nDo you want to add email address?"), MB_YESNO ) == IDNO )
				return;

			// insert ILL
			Ill.m_email = m_szTo;
			Ill.m_sent = 0;
			appConfig.m_SQL.SetExternIllSet( &Ill, m_szTo, TRUE );
		}
	}

	// get collection id
	m_nCollectionID = m_ctrlCollection.GetItemData( m_ctrlCollection.GetCurSel() );
	if( m_nCollectionID < 0 )
		return;

	// check fees
	if( m_dUserFeeMax > 0 && m_dServiceFee + m_dCopyrightFee > m_dUserFeeMax )
	{
		CString szMessage;
		szMessage.Format( _T("Attention:\n\nThe fees exceed the users max fee of %f. Continue sending request?"), m_dUserFeeMax );
		if( AfxMessageBox( szMessage, MB_YESNO ) == IDNO )
			return;
	}

	// set status
	SetDlgItemText( IDC_STATIC_STATUS, _T("Checking files...") );

	// build file list for attachment and/or removal
	for( INT nCount = 0; nCount < m_ctrlFiles.GetCount(); nCount++ )
	{
		// get from file
		m_ctrlFiles.GetLBText( nCount, szFileFrom );
		// split path
		TCHAR drive[_MAX_DRIVE];
		TCHAR dir[_MAX_DIR];
		TCHAR fname[_MAX_FNAME];
		TCHAR ext[_MAX_EXT];
		_tsplitpath_s( szFileFrom, drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, ext, _MAX_EXT );

		// send via attachment
		if( m_nSendType == SEND_ATTACH || m_bManual )
		{
			// build file name
			if( m_bManual )
			{
				CString szTemp;
				CTime tTime = CTime::GetCurrentTime();

				// add description
				szTemp = m_szDescription;
				// remove trailing '.'
				if( szTemp.Right( 1 ) == '.' )
					szTemp.Delete( szTemp.GetLength() );
				// replace macro with non tabbed date
				szTemp.Replace( _T("(DATE)"), appConfig.GetFormattedDateTime( TRUE, FALSE ) );
				// correct file name
				CorrectFilename( &szTemp );

				// build destination path
				if( m_bSendMultiple )
					szFileTo.Format( _T("%s_%ld_%s%s"), szTemp, nCount, tTime.Format( _T("%j%H%M%S") ), ext );
				else
					szFileTo.Format( _T("%s_%s%s"), szTemp, tTime.Format( _T("%j%H%M%S") ), ext );			
			}
			else
			{
				ULONGLONG lFileSize = 0;
				// gather file sizes
				CFileStatus fileStatus;
				CFile::GetStatus( szFileFrom, fileStatus );
				lFileSize += fileStatus.m_size;
				if( lFileSize >= appConfig.m_Email.nAttachmentmaxBytes * 1024 )
				{
					AfxMessageBox( IDS_ERROR_ATTACHMENT_MAX, MB_OK | MB_ICONEXCLAMATION );
					return;
				}

				// build destination path, including drive and path for attachment
				if( m_bSendMultiple )
					szFileTo.Format( _T("%s%s%.8ld_%d%s"), drive, dir, m_nItemID, nCount, ext );
				else
					szFileTo.Format( _T("%s%s%.8ld%s"), drive, dir, m_nItemID, ext );
			}

			// set file pair
			FILE_PAIR Files;
			Files.szFileFrom = szFileFrom;
			Files.szFileTo = szFileTo;
			// add to delete list
			m_aFiles.Add( Files );
		}
		// add to delete list
		else
		{
			// set file name
			szFileTo.Format( _T("%.8ld_%ld%s"), m_nItemID, m_nUserCode, ext );

			// set file pair
			FILE_PAIR Files;
			Files.szFileFrom = szFileFrom;
			Files.szFileTo = szFileTo;
			// add to delete list
			m_aFiles.Add( Files );
		}
	}

	// set status
	SetDlgItemText( IDC_STATIC_STATUS, _T("Getting email...") );

	// get request
	REQUEST_SET Request;
	appConfig.m_SQL.GetRequestSet( &Request, m_nItemID );
	if( m_bManual )
		Request.m_status_id = STATUS_ID_COMPLETE;

	// get status description
	STATUS_LOOKUP Status;
	appConfig.m_SQL.GetDescriptionStatus( &Status, Request.m_status_id );

	// get message
	if( m_nSendType == SEND_WEB )
	{
		// read message
		if( !Status.szMessageFile.IsEmpty() )
			m_szMessage = appConfig.ReadFile( Status.szMessageFile );
		else if( Request.m_external_id > 0 && !Status.szMessageFileExt.IsEmpty() )
			m_szMessage = appConfig.ReadFile( Status.szMessageFileExt );
		else
			m_szMessage = appConfig.ReadFile( appConfig.m_Email.szSendMessageFile );
	}
	else if( m_nSendType == SEND_FTP )
	{
		if( m_bManual )
		{
			// read message
			m_szMessage = appConfig.ReadFile( appConfig.m_Email.szFTPManualFile );
		}
		else
		{
			// read message
			if( !Status.szMessageFile.IsEmpty() )
				m_szMessage = appConfig.ReadFile( Status.szMessageFile );
			else if( Request.m_external_id > 0 && !Status.szMessageFileExt.IsEmpty() )
				m_szMessage = appConfig.ReadFile( Status.szMessageFileExt );
			else
				m_szMessage = appConfig.ReadFile( appConfig.m_Email.szFTPMessageFile );
		}
	}
	else if( m_nSendType == SEND_ATTACH )
	{
		if( m_bManual )
		{
			// read message
			m_szMessage = appConfig.ReadFile( appConfig.m_Email.szAttachManualFile );
		}
		else
		{
			// read message
			if( !Status.szMessageFile.IsEmpty() )
				m_szMessage = appConfig.ReadFile( Status.szMessageFile );
			else if( Request.m_external_id > 0 && !Status.szMessageFileExt.IsEmpty() )
				m_szMessage = appConfig.ReadFile( Status.szMessageFileExt );
			else
				m_szMessage = appConfig.ReadFile( appConfig.m_Email.szAttachMessageFile );
		}
	}
	else
	{
		return;
	}

	// get external request user id
	if( Request.m_external_id > 0 )
	{
		USER_SET User;
		if( appConfig.m_SQL.GetExternalUserID( &User, m_szTo ))
		{
			CString szTemp;
			szTemp.Format( _T("%ld"), User.m_id );
			m_szMessage.Replace( _T("(USERID)"), szTemp );
			m_szMessage.Replace( _T("(USERPID)"), User.m_pwd );
		}
	}

	// special manual macros
	if( m_bManual )
	{
		// description
		m_szMessage.Replace( _T("(DESCRIPTION)"), m_szDescription );
		m_szSubject.Replace( _T("(DESCRIPTION)"), m_szDescription );
		// information
		m_szMessage.Replace( _T("(INFORMATION)"), m_szInformation );
		m_szSubject.Replace( _T("(INFORMATION)"), m_szInformation );
	}

	// set note in email
	m_szMessage.Replace( _T("(REQUESTNOTES)"), m_szDescription );
	m_szSubject.Replace( _T("(REQUESTNOTES)"), m_szDescription );

	// format message
	appConfig.FormatMacros( &m_szMessage, m_nItemID, m_nStaffID, STATUS_ID_COMPLETE, m_nLibraryID, m_nUserID, &m_aFiles );
	// format subject macros
	appConfig.FormatMacros( &m_szSubject, m_nItemID, m_nStaffID, STATUS_ID_COMPLETE );

	// preview email
	if( m_bPreviewEmail )
	{
		CDlgPreviewHTML dlgPreview;
		dlgPreview.m_bSend = TRUE;
		dlgPreview.m_szHTML = m_szMessage;
		dlgPreview.m_szSubject = m_szSubject;
		
		// show message
		if( dlgPreview.DoModal() != IDOK )
			return;

		// get new message
		m_szMessage = dlgPreview.m_szHTML;
		m_szSubject = dlgPreview.m_szSubject;
	}

	// show wait cursor
	CWaitCursor wait;

	// reset thumbnail
	m_wbPreview.Navigate(_T("about:blank"), NULL, NULL, NULL, NULL);

	// set status
	SetDlgItemText( IDC_STATIC_STATUS, _T("Sending File...") );

	// send/copy to server
	if( m_nSendType == SEND_WEB )
	{
		if( appConfig.m_General.bStoreFilesInDataBase )
		{
			// send file to web server
			if( !SendFileToServer() )
				return;
		}
		else
		{
			// send file to web server
			if( appConfig.m_General.bSendFilesViaFTP )
			{
				// check if external and send to server
				if( UserType.nExternal )
				{
					if( FTPFileToServer( appConfig.m_External.szFTPServer, appConfig.m_External.szFTPFolder, appConfig.m_External.szFTPUID, appConfig.m_External.szFTPPWD, &m_aFiles ) != S_OK )
						return;
				}
				else if( m_bManual )
				{
					if( FTPFileToServer( appConfig.m_FTP_ILL.szServerName, appConfig.m_FTP_ILL.szServerFolder, appConfig.m_FTP_ILL.szFTPUID, appConfig.m_FTP_ILL.szFTPPWD, &m_aFiles ) != S_OK )
						return;
				}
				else
				{
					if( FTPFileToServer( appConfig.m_FTP_WEB.szServerName, appConfig.m_FTP_WEB.szServerFolder, appConfig.m_FTP_WEB.szFTPUID, appConfig.m_FTP_WEB.szFTPPWD, &m_aFiles ) != S_OK )
						return;
				}
			}
			else
			{
				// check if external and send to server
				if( UserType.nExternal )
				{
					if( FTPFileToServer( appConfig.m_External.szFTPServer, appConfig.m_External.szFTPFolder, appConfig.m_External.szFTPUID, appConfig.m_External.szFTPPWD, &m_aFiles ) != S_OK )
						return;
				}
				else
				{
					if( !CopyFileToServer( &m_aFiles ))
						return;
				}
			}
		}
	}
	// send/copy to server via FTP
	else if( m_nSendType == SEND_FTP )
	{
		if( m_bManual )
		{
			if( FTPFileToServer( appConfig.m_FTP_ILL.szServerName, appConfig.m_FTP_ILL.szServerFolder, appConfig.m_FTP_ILL.szFTPUID, appConfig.m_FTP_ILL.szFTPPWD, &m_aFiles ) != S_OK )
				return;
		}
		else
		{
			if( FTPFileToServer( appConfig.m_FTP_WEB.szServerName, appConfig.m_FTP_WEB.szServerFolder, appConfig.m_FTP_WEB.szFTPUID, appConfig.m_FTP_WEB.szFTPPWD, &m_aFiles ) != S_OK )
				return;
		}
	}
	// send via attachment
	else if( m_nSendType == SEND_ATTACH )
	{
		// set attach as empty
		m_szAttach.Empty();

		// rename files for attachment
		for( INT nCount = 0; nCount < m_aFiles.GetCount(); nCount++ )
		{
			// get from file
			m_ctrlFiles.GetLBText( nCount, szFileFrom );

			// rename files
			BOOL bRenamed = FALSE;
			// loop to wait for file to free
			for( INT nTries = 0; nTries <= 30000; nTries++ )
			{
				CString szTries;
				szTries.Format( _T("Waiting to rename file... %d"), nTries);
				SetDlgItemText( IDC_STATIC_STATUS, szTries );
				// rename files
				if( _trename( szFileFrom, m_aFiles.GetAt( nCount ).szFileTo ) == S_OK )
				{
					bRenamed = TRUE;
					break;
				}
				else
				{
					DoEvents( this->GetSafeHwnd() );
				}
			}
			// rename file
			if( !bRenamed )
			{
				AfxMessageBox( _T("Send Dialog: Error renaming files"), MB_OK );
				EndDialog( IDCANCEL );
				return;
			}

			// add to attach list
			m_szAttach += m_aFiles.GetAt( nCount ).szFileTo;
			m_szAttach += _T(";");
			// rename for remove
			m_aFiles.GetAt( nCount ).szFileFrom = m_aFiles.GetAt( nCount ).szFileTo;
		}
	}
	else
	{
		// just to be sure
		m_szAttach.Empty();
	}

	// send message
	if( !m_bDeferEmail || m_nSendType == SEND_ATTACH )
	{
		// send it
		if( !SendMsg.SendEmail( m_szName, m_szFrom, m_szTo, m_szSubject, m_szMessage, m_szAttach ))
		{
			AfxMessageBox( _T("Send Dialog: Error sending email"), MB_OK );
			EndDialog( IDCANCEL );
			return;
		}
	}

	// set status
	SetDlgItemText( IDC_STATIC_STATUS, _T("Updating request...") );

	// not manual update
	if( !m_bManual )
	{
		// loop through files
		for( INT nCount = 0; nCount < m_aFiles.GetCount(); nCount++ )
		{
			REQUEST_SET Request;
			// get request
			appConfig.m_SQL.GetRequestSet( &Request, m_nItemID );
			// set variables		
			Request.m_staff_id = m_nStaffID;
			Request.m_library_id = m_nLibraryID;
			Request.m_type = m_nSendType;
			Request.m_status_id = STATUS_ID_COMPLETE;
			Request.m_file = m_aFiles.GetAt( nCount ).szFileTo;
			Request.m_fee_service = m_dServiceFee;
			Request.m_fee_copyright = m_dCopyrightFee;
			Request.m_fee_misc = m_dMiscFee;
			Request.m_date_out = COleDateTime::GetCurrentTime();
			Request.m_touched = TRUE;
			Request.m_material = m_nMaterial;
			Request.m_collection_id = m_nCollectionID;
			Request.m_notes = m_szDescription;
			Request.m_retain = 0;
			// update request
			appConfig.m_SQL.SetRequestSet( &Request );

			// save status
			m_nStatus = Request.m_status_id;
		}

		// save notes pick list
		CString szNotes;
		if( m_ctrlDescription.FindString( 0, m_szDescription ) == CB_ERR )
			m_szaDescription.InsertAt( 0, m_szDescription );
		INT nCount = m_szaDescription.GetCount();
		if( nCount > NOTES_PICK_LIST )
			nCount = NOTES_PICK_LIST;
		for( INT nIndex = 0; nIndex < nCount; nIndex++ )
			szNotes += m_szaDescription.GetAt( nIndex ) + _T("\n\r");
		AfxGetApp()->WriteProfileString( _T("Settings"), _T("PickList_Notes"), szNotes );
	}
	else
	{
		EXTERNAL_ILL_SET Ill;
		// get ILL
		appConfig.m_SQL.GetExternIllSet( &Ill, m_szTo );
		// update ILL sent
		Ill.m_sent++;
		appConfig.m_SQL.SetExternIllSet( &Ill, m_szTo );

		// get links
		CString szTemp;
		szTemp = _T("(FTPLINK)");
		appConfig.FormatMacros( &szTemp, m_nItemID, m_nStaffID, STATUS_ID_COMPLETE, m_nLibraryID, m_nUserID, &m_aFiles );

		// update history
		appConfig.m_SQL.UpdateExternIllHistory( m_nStaffID, Ill.m_id, m_szDescription, szTemp );

		// save notes pick list
		CString szNotes;
		if( m_ctrlInformation.FindString( 0, m_szInformation ) == CB_ERR )
			m_szaInformation.InsertAt( 0, m_szInformation );
		INT nCount = m_szaInformation.GetCount();
		if( nCount > NOTES_PICK_LIST )
			nCount = NOTES_PICK_LIST;
		for( INT nIndex = 0; nIndex < nCount; nIndex++ )
			szNotes += m_szaInformation.GetAt( nIndex ) + _T("\n\r");
		AfxGetApp()->WriteProfileString( _T("Settings"), _T("PickList_Notes"), szNotes );
	}

	// set status
	SetDlgItemText( IDC_STATIC_STATUS, _T("Finishing...") );

	// delete file in OnDocumentComplete
	if( m_bDeleteFile )
	{
		// loop and delete
		for( INT_PTR nCount = 0; nCount < m_aFiles.GetCount(); nCount++ )
		{
			BOOL bDeleted = FALSE;
			CString szFile = m_aFiles.GetAt( nCount ).szFileFrom;
			// loop to wait for file to free
			for( INT nTries = 0; nTries <= 30000; nTries++ )
			{
				CString szTries;
				szTries.Format( _T("Waiting to delete file... %d"), nTries);
				SetDlgItemText( IDC_STATIC_STATUS, szTries );
				// delete files
				if( DeleteFile( szFile ) != 0 )
				{
					bDeleted = TRUE;
					break;
				}
				else
				{
					DoEvents( this->GetSafeHwnd() );
				}
			}
			if( !bDeleted )
			{
				DWORD dw = GetLastError();
				AfxMessageBox( _T("Send Dialog: Error deleteing files"), MB_OK );
			}
		}
	}

	// save collection
	if( appConfig.m_General.bUseSitckyCollection )
	{
		AfxGetApp()->WriteProfileInt( _T("Settings"), _T("StickyCollection"), m_nCollectionID );
		AfxGetApp()->WriteProfileInt( _T("Settings"), _T("StickyMaterial"), m_nMaterial );
	}

	// close dialog
	CDialog::OnOK();
}

void CDlgSendRequest::OnBnClickedCancel()
{
	// close dialog
	OnCancel();
}

void CDlgSendRequest::OnBnClickedButtonBrowseFile()
{
	USES_CONVERSION;

	// get files
	if( !GetFiles() )
		return;

	// update data
	UpdateData();

	// set combobox item
	m_ctrlFiles.SetCurSel( m_nFileIndex );

	// thumnail enabled
	if( m_bEnableThumbnail )
	{
		// get file from
		CString szFileFrom;
		GetDlgItemText( IDC_COMBO_FILE_NAME, szFileFrom );
		// navigate to file
		m_wbPreview.Navigate( szFileFrom, NULL, NULL, NULL, NULL );
	}
}

void CDlgSendRequest::OnBnClickedButtonThumbnail()
{
	// update data
	UpdateData();

	// toggle
	m_bShowThumbnail = !m_bShowThumbnail;

	CRect rect;
	GetWindowRect( rect );
	// set window position
	if( m_bShowThumbnail )
		SetWindowPos( NULL, 0, 0, m_nWindowWidthShow, rect.Height(), SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
	else
		SetWindowPos( NULL, 0, 0, m_nWindowWidthNoShow, rect.Height(), SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );

	// save
	AfxGetApp()->WriteProfileInt( _T("Settings"), _T("ShowThumbnail"), m_bShowThumbnail );
}

BOOL CDlgSendRequest::GetFiles()
{
	// Create an Open dialog
	DWORD dwFlags = OFN_FILEMUSTEXIST | OFN_LONGNAMES | OFN_PATHMUSTEXIST;
	// allow multiple send
	if( m_bSendMultiple )
		dwFlags |= OFN_ALLOWMULTISELECT;
	// create file dialog
	CFileDialog fileDlg( TRUE, NULL, NULL, dwFlags, appConfig.m_General.szFileTypesFormat, this );
	// increase buffer
	TCHAR *fileNameBuffer = new TCHAR[OFN_BUFFER_SIZE];
	memset( fileNameBuffer, NULL, OFN_BUFFER_SIZE);
	fileDlg.m_pOFN->lpstrFile = fileNameBuffer;
	fileDlg.m_pOFN->nMaxFile = OFN_BUFFER_SIZE;
	// set title
	CString szText;
	if( m_nItemID > 0 )
		szText.Format( _T("Select file for: %.8ld"), m_nItemID );
	else
		szText.Format( _T("Select file(s) for manual send"), m_nItemID );
	fileDlg.m_pOFN->lpstrTitle = szText;
	// Display the file dialog and get file name
	if( fileDlg.DoModal() == IDOK )
	{
		CString szDesc;
		CString szFile;
		CString szPath;
		INT nCount = 0;
		// clear string arrays
		m_ctrlFiles.ResetContent();
		m_csaDescriptions.RemoveAll();
	    POSITION pos = fileDlg.GetStartPosition();
		while( pos )
		{
			szPath = fileDlg.GetNextPathName( pos );
			szPath.Replace( _T("\\\\"), _T("\\") );
			nCount = m_ctrlFiles.AddString( szPath );
			m_ctrlFiles.GetLBText( nCount, szFile );
			// get only the file name without extension
			INT nStart = szFile.ReverseFind( '\\' ) + 1;
			INT nEnd = szFile.ReverseFind( '.' ) - nStart;
			szFile = szFile.Mid( nStart, nEnd );
			// set default description for manual send
			if( m_nItemID > 0 )
				szDesc = m_szDescription;				
			else
			{
				// sending manual
				m_bManual = TRUE;
				if( !appConfig.m_General.szDefaultDescription.IsEmpty() )
					szDesc.Format( _T("%s %d %s"), appConfig.m_General.szDefaultDescription, nCount + 1, szFile );
				else
					szDesc = szFile;
			}
			m_csaDescriptions.SetAtGrow( nCount, szDesc );
		}
		// set rang on spin control
		//m_cspDescription.SetRange( 0, nCount );
		// reset index
		//m_nDescriptionIndex = 0;
		// delete buffer
		delete fileNameBuffer;
		// retrun
		return TRUE;
	}
	else
	{
		DWORD errCode = CommDlgExtendedError();
		switch( errCode )
		{
		case 0:
			TRACE(_T("User cancelled Extract dialog\n"));
			break;
		case FNERR_BUFFERTOOSMALL:
			AfxMessageBox(_T("Too many files selected. Try again with fewer files."));
			break;
		default:
			AfxMessageBox(_T("An error occurred"));
			break;
		}
	}
	// delete buffer
	delete fileNameBuffer;
	// retrun
	return FALSE;
}

void CDlgSendRequest::CorrectFilename(CString* pszFileName)
{
	// remove bad characters
	pszFileName->Remove( '*' );
	pszFileName->Remove( ':' );
	pszFileName->Remove( '?' );
	pszFileName->Remove( '$' );
	pszFileName->Remove( '\'' );
	pszFileName->Remove( '\"' );
	pszFileName->Remove( '/' );
	pszFileName->Remove( '|' );
	pszFileName->Remove( '#' );
	pszFileName->Remove( '<' );
	pszFileName->Remove( '>' );
	pszFileName->Remove( '\r' );
	// replace bad characters with words
	pszFileName->Replace( _T("\n"), _T(" ") );
	pszFileName->Replace( _T("&"), _T("and") );

	// replace latin characters
	for( INT nIndex = 0; nIndex < pszFileName->GetLength(); nIndex++ )
	{
		UINT nChar = 0;
		// convert to ascii
		nChar = appConfig.Convert2Ascii( pszFileName->GetAt( nIndex ));
		if( nChar )
			pszFileName->SetAt( nIndex, nChar );
	}
	// trim
	pszFileName->Trim();
}

BOOL CDlgSendRequest::CopyFileToServer(CFilePair* pFiles)
{
	//CString szFile;
	CString szFileTo;
	CString szFileFrom;
	TCHAR src[MAX_PATH + 1] = _T("");
	TCHAR dest[MAX_PATH + 1] = _T("");

	// copy files to the web server
	for( INT nCount = 0; nCount < pFiles->GetCount(); nCount++ )
	{
		// set path
		szFileTo.Format( _T("%s\\%s"), appConfig.m_General.szRootFolder, pFiles->GetAt( nCount ).szFileTo );
		szFileFrom = pFiles->GetAt( nCount ).szFileFrom;

		// copy file names for copy operation
		_stprintf_s( src, _T("%s%c") , szFileFrom, _T('\0') ) ;
		_stprintf_s( dest, _T("%s%c") , szFileTo, _T('\0') ) ;

		// copy with no UI
		if( appConfig.m_General.bFileCopyNoUI )
		{
			if( CopyFile( src, dest, FALSE ) == FALSE )
			{
				CString lpMsgBuf;
				FormatMessage( 
					FORMAT_MESSAGE_ALLOCATE_BUFFER | 
					FORMAT_MESSAGE_FROM_SYSTEM | 
					FORMAT_MESSAGE_IGNORE_INSERTS,
					NULL,
					GetLastError(),
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
					(LPTSTR) &lpMsgBuf,
					0,
					NULL );
				// Process any inserts in lpMsgBuf.
				// ...
				// Display the string.
				AfxMessageBox( lpMsgBuf, MB_OK | MB_ICONINFORMATION );
				return FALSE;
			}
		}
		else
		{
			// copy file to server
			SHFILEOPSTRUCT FileOp;

			FileOp.hwnd = AfxGetMainWnd()->GetSafeHwnd();
			FileOp.wFunc = FO_COPY;
			FileOp.pFrom = src;
			FileOp.pTo = dest;
			FileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;;
			FileOp.lpszProgressTitle = NULL;

			// it not successful return to try again
			INT nRetVal = SHFileOperation( &FileOp );
			if( nRetVal > 0 )
			{
				CString szMessage;
				szMessage.Format( _T("Send Dialog: Error copying files (%d)"), nRetVal );
				AfxMessageBox( szMessage, MB_OK | MB_ICONINFORMATION );
				return FALSE;
			}
		}
	}
	return TRUE;
}

BOOL CDlgSendRequest::SendFileToServer()
{
	AfxMessageBox( _T("Not currently implemented. Please change INI file.") );
	return FALSE;
}

LRESULT CDlgSendRequest::FTPWithStatus(CString szServer, CString szFolder, CString szUID, CString szPWD, CFilePair* pFiles)
{
	// remove the "ftp://" protocol
	if( szServer.Left( 6 ).CompareNoCase( _T("ftp://") ) == 0 )
		szServer = szServer.Right( szServer.GetLength() - 6 );

	// add backslashes
	if( !szFolder.IsEmpty() && szFolder.Left( 1 ).CompareNoCase( _T("/") ) != 0 )
		szFolder = _T("/") + szFolder;
	if( !szFolder.IsEmpty() && szFolder.Right( szFolder.GetLength() ).CompareNoCase( _T("/") ) != 0 )
		szFolder = szFolder + _T("/");

	// transfer dialog
	CFTPTransferDlg dlg;
	dlg.m_bPasv = TRUE;
	dlg.m_sServer = szServer;
	dlg.m_sUserName = szUID;
	dlg.m_sPassword = szPWD;

	// copy files to server
	for( INT nCount = 0; nCount < pFiles->GetCount(); nCount++ )
	{
		dlg.m_sRemoteFile = szFolder + pFiles->GetAt( nCount ).szFileTo;
		dlg.m_sLocalFile = pFiles->GetAt( nCount ).szFileFrom;
		dlg.m_bDownload = FALSE;
		dlg.m_bBinary = TRUE;
		if( dlg.DoModal() != IDOK )
			return S_FALSE;
	}
	return S_OK;
}

LRESULT CDlgSendRequest::FTPFileToServer(CString szServer, CString szFolder, CString szUID, CString szPWD, CFilePair* pFiles)
{
	// FTP with status bypass
	if( appConfig.m_FTP_ILL.bShowStatus || appConfig.m_FTP_WEB.bShowStatus )
		return FTPWithStatus( szServer, szFolder, szUID, szPWD, pFiles );

	// upload files
	CInternetSession* pInetSession;
	CFtpConnection* pFtpConnection;
	CString strServerName;
	CString strObject;
	INTERNET_PORT nPort;
	DWORD dwServiceType;
	CString szFileTo;
	CString szFileFrom;

	// the CInternetSession will not be closed or deleted until the dialog is closed
	pInetSession = new CInternetSession( _T( "FileTransfer" ), 1, PRE_CONFIG_INTERNET_ACCESS );

	// Alert the user if the internet session could not be started and close app
	if( !pInetSession )
	{
		AfxMessageBox( _T("Error creating FTP server session. Please try again."), MB_OK );
		return S_FALSE;
	}

	// check to see if this is a reasonable URL --
	// ie "ftp://servername/dirs" or just "servername/dirs"
	if( !AfxParseURL( szServer, dwServiceType, strServerName, strObject, nPort ))
	{
		// try adding the "ftp://" protocol
		CString strFtpURL = _T("ftp://");
		strFtpURL += szServer;

		if( !AfxParseURL( strFtpURL, dwServiceType, strServerName, strObject, nPort ))
		{
			AfxMessageBox( _T("Error getting to FTP server. Please try again."), MB_OK );
			return S_FALSE;
		}
	}
	// Now open a FTP connection to the server
	if(( dwServiceType == INTERNET_SERVICE_FTP ) && !strServerName.IsEmpty() )
	{
		try
		{
			pFtpConnection = pInetSession->GetFtpConnection( strServerName, szUID, szPWD, nPort, TRUE );
		}
		catch( CInternetException* pEx )
		{
			// catch errors from WinINet
			TCHAR szErr[1024];
			if( pEx->GetErrorMessage( szErr, 1024 ))
				AfxMessageBox( szErr, MB_OK );
			else
				AfxMessageBox( _T("Error connecting to FTP server. Please try again."), MB_OK );
			pEx->Delete();
			pFtpConnection = NULL;
			return S_FALSE;
		}
	}
	else
	{
		AfxMessageBox( _T("Error FTP URL not valid. Please try again."), MB_OK );
		return S_FALSE;
	}

	// change to server folder
	if( !szFolder.IsEmpty() )
	{
		if( !pFtpConnection->SetCurrentDirectory( szFolder ))
		{
			AfxMessageBox( _T("Error setting FTP folder. Please try again."), MB_OK );
			return S_FALSE;
		}
	}

	// copy files to server
	for( INT nCount = 0; nCount < pFiles->GetCount(); nCount++ )
	{
		// set path
		szFileTo = pFiles->GetAt( nCount ).szFileTo;
		szFileFrom = pFiles->GetAt( nCount ).szFileFrom;

		// check for file
		CFtpFileFind finder( pFtpConnection );	
		if( finder.FindFile( szFileTo ))
		{
			if( AfxMessageBox( _T("Error request file already exists on FTP server.\n\nOverwrite file?"), MB_YESNO ) == IDNO )
			{
				return S_FALSE;
			}
		}

		// Upload file
		if( !pFtpConnection->PutFile( szFileFrom, szFileTo ))
		{
			AfxMessageBox( _T("Error putting file on FTP server. Please try again."), MB_OK );
			return S_FALSE;
		}

	}

	// close FTP connection
	if( pFtpConnection != NULL )
	{
		pFtpConnection->Close();
		delete pFtpConnection;
	}
	if( pInetSession != NULL )
	{
		pInetSession->Close();
		delete pInetSession;
	}

	return S_OK;
}

void CDlgSendRequest::OnCbnSelchangeComboCollection()
{
	// update data
	UpdateData();

	// get collection id
	m_nCollectionID = m_ctrlCollection.GetItemData( m_ctrlCollection.GetCurSel() );

	// check for electronic
	COLLECTION_LOOKUP Collection;
	appConfig.m_SQL.GetDescriptionCollection( &Collection, m_nCollectionID );
	// set electronc
	m_nMaterial = Collection.nElectronic;

	// update data
	UpdateData( FALSE );
}

void CDlgSendRequest::OnBnClickedButtonOpen()
{
	// update data
	UpdateData();

	// get file from
	CString szFileFrom;
	GetDlgItemText( IDC_COMBO_FILE_NAME, szFileFrom );

	// check for file
	if( szFileFrom.IsEmpty() )
	{
		AfxMessageBox( _T("No file specified"), MB_OK | MB_ICONSTOP );
		return;
	}

	// view file use shellexecute
	ShellExecute( m_hWnd, _T("open"), szFileFrom, NULL, NULL, SW_SHOW );
}

void CDlgSendRequest::OnBnClickedButtonDelete()
{
	// warn
	CString szMessage;
	szMessage.Format( _T("WARNING: This will permantly delete this PDF file and close the Send dialog.\n\nAre you sure you want to continue?") );
	if( AfxMessageBox( szMessage, MB_YESNO ) == IDNO )
		return;
	// confirm really
	CDlgConfirm dlgConfirm;
	dlgConfirm.m_szAction = _T("This will permantly this PDF file.\n\nAre you sure you want to proceed?");
	if( dlgConfirm.DoModal() != IDOK )
		return;

	// reset thumbnail
	m_wbPreview.Navigate( _T("About:Blank"), NULL, NULL, NULL, NULL );

	// get file from
	CString szFile;
	GetDlgItemText( IDC_COMBO_FILE_NAME, szFile );

	// delete file
	BOOL bDeleted = FALSE;
	// loop to wait for file to free
	for( INT nTries = 0; nTries <= 30000; nTries++ )
	{
		CString szTries;
		szTries.Format( _T("Waiting to delete file... %d"), nTries);
		SetDlgItemText( IDC_STATIC_STATUS, szTries );
		// delete files
		if( DeleteFile( szFile ) != 0 )
		{
			bDeleted = TRUE;
			break;
		}
		else
		{
			DoEvents( this->GetSafeHwnd() );
		}
	}
	if( !bDeleted )
	{
		DWORD dw = GetLastError();
		AfxMessageBox( _T("Send Dialog: Error deleteing files"), MB_OK );
	}

	// close dialog
	OnCancel();
}

BOOL CDlgSendRequest::FormatMacros(CString* pszString)
{
	CString szTemp;

	// check for user deleted
	if( m_User.m_id == -1 )
	{
		// replace strings
		pszString->Replace( _T("(USERNAME)"), _T("[User Deleted]") );
		pszString->Replace( _T("(USEREMAIL)"), _T("[User Deleted]") );
		pszString->Replace( _T("(USERPHONE)"), _T("[User Deleted]") );
		pszString->Replace( _T("(USERFAX)"), _T("[User Deleted]") );
		pszString->Replace( _T("(USERCOMPANY)"), _T("[User Deleted]") );
	}
	else
	{
		// replace strings
		pszString->Replace( _T("(USERNAME)"), m_User.m_name );
		pszString->Replace( _T("(USEREMAIL)"), m_User.m_email );
		pszString->Replace( _T("(USERPHONE)"), m_User.m_phone );
		pszString->Replace( _T("(USERFAX)"), m_User.m_fax );
		pszString->Replace( _T("(USERCOMPANY)"), m_User.m_company );
	}

	pszString->Replace( _T("(PRIORITY)"), m_pszaPriority->GetAt( m_Request.m_priority_id ));
	pszString->Replace( _T("(METHOD)"), m_pszaMethod->GetAt( m_Request.m_method_id ));
	pszString->Replace( _T("(LIBRARY)"), m_pszaLibrary->GetAt( m_Request.m_library_id ));
	szTemp.Format( _T("%d"), m_Request.m_redirected );
	pszString->Replace( _T("(REDIRECTED)"), szTemp );
	pszString->Replace( _T("(ILLYESNO)"), m_pszaILL->GetAt( m_Request.m_ill_id ));
	pszString->Replace( _T("(PROJECT)"), m_Request.m_project );

	return TRUE;
}

void CDlgSendRequest::DoEvents( HWND hWnd_i )
{
   MSG stMsg = { 0 };
   while( PeekMessage( &stMsg, hWnd_i, 0, 0, PM_REMOVE ))
   {
       TranslateMessage( &stMsg );
       DispatchMessage( &stMsg );
    }
}
